#!/usr/bin/env python3
"""
提取并测试特定偏移处的潜在映射表
"""

import os

def extract_and_test_specific_offsets():
    """提取特定偏移处的256字节并测试"""
    print("🔍 === 提取并测试潜在映射表 ===\n")
    
    # 已知的映射
    known_mappings = {
        0xa1: ord('m'),
        0xf3: ord('o'),
        0x6b: ord('d'),
        0x31: ord('e'),
        0xb0: ord('l'),
        0x69: ord('"'),
        0x01: ord(':'),
        0x90: ord(' ')
    }
    
    # 一些可能包含映射表的偏移
    test_offsets = [
        0x05090560,  # 找到的包含目标字节的位置
        0x05090400,  # 往前一些
        0x05090000,  # 对齐的位置
        0x04000000,  # 其他段
        0x03000000,
        0x02000000,
        0x01c0cd80,  # .rodata段
    ]
    
    with open('Lingma', 'rb') as f:
        binary_data = f.read()
    
    with open('decoded_result.bin', 'rb') as f:
        encrypted_data = f.read()
    
    for offset in test_offsets:
        if offset + 256 <= len(binary_data):
            # 提取256字节
            table = binary_data[offset:offset+256]
            
            # 验证已知映射
            matches = sum(1 for src, dst in known_mappings.items() if table[src] == dst)
            
            if matches >= 4:  # 至少4个匹配
                print(f"\n偏移 0x{offset:08x}: {matches}/8 个已知映射匹配")
                
                # 保存表
                filename = f'table_0x{offset:08x}.bin'
                with open(filename, 'wb') as f:
                    f.write(table)
                
                # 测试解密
                decrypted = bytearray()
                for byte in encrypted_data[:500]:
                    decrypted.append(table[byte])
                
                # 检查结果
                printable = sum(1 for b in decrypted if 32 <= b <= 126)
                json_features = sum(1 for c in [ord('"'), ord(':'), ord(',')] if c in decrypted[:100])
                
                print(f"  可打印字符: {printable}/500")
                print(f"  JSON特征: {json_features}")
                
                if printable > 300 and json_features >= 2:
                    print(f"  ✅ 可能是正确的映射表!")
                    
                    # 显示示例
                    sample = bytearray()
                    for b in decrypted[:200]:
                        sample.append(b if 32 <= b <= 126 else ord('?'))
                    
                    print(f"  示例: {bytes(sample).decode('ascii')[:100]}...")
                    
                    # 保存完整解密
                    full_decrypted = bytearray()
                    for byte in encrypted_data:
                        full_decrypted.append(table[byte])
                    
                    with open(f'decrypted_0x{offset:08x}.txt', 'wb') as f:
                        f.write(full_decrypted)

def search_byte_sequence():
    """搜索特定的字节序列"""
    print("\n\n🔎 === 搜索特定字节序列 ===")
    
    # 搜索包含 "model" 对应密文的序列
    # model 的密文是: a1 f3 6b 31 b0
    search_pattern = bytes([0xa1, 0xf3, 0x6b, 0x31, 0xb0])
    
    with open('Lingma', 'rb') as f:
        data = f.read()
    
    pos = 0
    found_positions = []
    
    while True:
        pos = data.find(search_pattern, pos)
        if pos == -1:
            break
        found_positions.append(pos)
        pos += 1
    
    print(f"找到 'model' 密文序列 {len(found_positions)} 次")
    
    # 检查这些位置周围是否有映射表
    for i, pos in enumerate(found_positions[:10]):
        print(f"\n位置 {i+1}: 0x{pos:08x}")
        
        # 检查前256字节
        if pos >= 256:
            check_offset = pos - 256
            table = data[check_offset:check_offset+256]
            
            # 验证映射
            if table[0xa1] == ord('m') and table[0xf3] == ord('o'):
                print(f"  ✅ 在偏移 0x{check_offset:08x} 找到可能的映射表!")
                
                with open(f'found_table_{i}.bin', 'wb') as f:
                    f.write(table)

def analyze_go_data_structures():
    """分析Go的数据结构"""
    print("\n\n📦 === 分析Go数据结构 ===")
    
    # Go的slice结构：指针(8字节) + 长度(8字节) + 容量(8字节)
    # 查找可能指向256字节数组的结构
    
    with open('Lingma', 'rb') as f:
        data = f.read()
    
    import struct
    
    # 在数据段查找
    data_section_start = 0x0533e020  # .data段起始
    data_section_size = 0x00C7E0    # 大约
    
    if data_section_start + data_section_size <= len(data):
        print(f"扫描.data段 (0x{data_section_start:08x} - 0x{data_section_start+data_section_size:08x})")
        
        # 查找可能的slice结构
        for offset in range(data_section_start, data_section_start + data_section_size - 24, 8):
            # 读取三个8字节值
            ptr = struct.unpack('<Q', data[offset:offset+8])[0]
            length = struct.unpack('<Q', data[offset+8:offset+16])[0]
            cap = struct.unpack('<Q', data[offset+16:offset+24])[0]
            
            # 检查是否可能是指向256字节数组的slice
            if length == 256 and cap == 256 and 0x400000 < ptr < 0x6000000:
                print(f"\n可能的映射表slice at 0x{offset:08x}:")
                print(f"  指针: 0x{ptr:016x}")
                print(f"  长度: {length}")
                print(f"  容量: {cap}")
                
                # 尝试读取指向的数据
                if ptr < len(data):
                    table = data[ptr:ptr+256]
                    
                    # 验证
                    known = {0xa1: ord('m'), 0xf3: ord('o'), 0x6b: ord('d')}
                    matches = sum(1 for k, v in known.items() if table[k] == v)
                    
                    if matches >= 2:
                        print(f"  ✅ 验证通过! {matches}/3")
                        with open(f'go_slice_table_0x{ptr:08x}.bin', 'wb') as f:
                            f.write(table)

if __name__ == "__main__":
    extract_and_test_specific_offsets()
    search_byte_sequence()
    analyze_go_data_structures()
    
    print("\n\n🧪 === 测试所有生成的表 ===")
    
    # 测试所有生成的表文件
    import glob
    table_files = glob.glob('*.bin')
    
    if table_files:
        with open('decoded_result.bin', 'rb') as f:
            encrypted = f.read()
        
        for table_file in table_files:
            if os.path.getsize(table_file) == 256:
                with open(table_file, 'rb') as f:
                    table = f.read()
                
                # 快速测试
                test_data = encrypted[:100]
                decrypted = bytes(table[b] for b in test_data)
                
                if b'"' in decrypted and b':' in decrypted:
                    print(f"\n✅ {table_file} 产生了JSON特征!")
                    
                    # 完整解密
                    full = bytes(table[b] for b in encrypted)
                    
                    # 保存
                    output_name = f'SUCCESS_{table_file}.txt'
                    with open(output_name, 'wb') as f:
                        f.write(full)
                    
                    print(f"已保存到 {output_name}")
                    
                    # 显示前200字符
                    preview = bytearray()
                    for b in full[:200]:
                        preview.append(b if 32 <= b <= 126 else ord('?'))
                    
                    print(f"预览: {bytes(preview).decode('ascii')}...")
    
    print("\n\n💡 完成!")
    print("检查 SUCCESS_*.txt 文件查看成功解密的结果")